﻿using System;
using System.Web;
using System.Web.Services;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Service;

namespace ECommerce
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://www.godbuying.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class PictureHandler : IHttpHandler
    {
		private IPictureService _PictureService;

        public int PictureSize
        {
            get
            {
                return CommonHelper.QueryStringInt("picturesize");
            }
        }

		public int ProductID
		{
			get
			{
				return CommonHelper.QueryStringInt("productid");
			}
		}

        public int PictureID
        {
            get
            {
                return CommonHelper.QueryStringInt("pictureid");
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            var thePicture = GetThePicture();

            if (thePicture != null)
            {
                context.Response.ContentType = thePicture.Extension;

                // resize
                using (MemoryStream ms = new MemoryStream(thePicture.PictureBinary.ToArray()))
                {
                    var b = new Bitmap(ms);

                    var newSize = CalculateDimensions(b.Size);

                    if (newSize.Width < 1)
                    {
                        newSize.Width = 1;
                    }
                    if (newSize.Height < 1)
                    {
                        newSize.Height = 1;
                    }

                    var newBitMap = new Bitmap(newSize.Width, newSize.Height);
                    var g = Graphics.FromImage(newBitMap);
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                    g.DrawImage(b, 0, 0, newSize.Width, newSize.Height);
                    var ep = new EncoderParameters();
                    ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ImageQuality);

                    using (MemoryStream ms1 = new MemoryStream())
                    {
                        byte[] bdata = null;
                        newBitMap.Save(ms1, GetImageCodeInfo("image/jpeg"), ep);
                        ms1.Position = 0;
                        bdata = new byte[ms1.Length];

                        ms1.Read(bdata, 0, Convert.ToInt32(ms1.Length));
                        ms1.Flush();

						context.Response.Cache.SetExpires(DateTime.Now.AddDays(1));
						context.Response.Cache.SetCacheability(HttpCacheability.Public);
						context.Response.Cache.SetValidUntilExpires(true);
						context.Response.ContentType = thePicture.Extension;
                        context.Response.BinaryWrite(bdata);
                        context.Response.End();
                    }

                    newBitMap.Dispose();
                    b.Dispose();
                }
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public long ImageQuality
        {
            get
            {
                return 100L;
            }
        }

		private Data.Entity.Picture GetThePicture()
		{
			if(PictureID <= 0 && ProductID <= 0)
			{
				return null;
			}

			if(ProductID > 0)
			{
				return GetDefaultPicture();
			}

			if(_PictureService == null)
			{
				_PictureService = new PictureService();
			}

			return _PictureService.GetPicture(PictureID);
		}

		private Data.Entity.Picture GetDefaultPicture()
		{
			if(ProductID <= 0)
			{
				return null;
			}

			if(_PictureService == null)
			{
				_PictureService = new PictureService();
			}

			return _PictureService.GetTheProductDefaultPicture(ProductID);
		}

        /// <summary>
        /// Returns the first ImageCodeInfo instance with the specified mime type. Some people try to get the ImageCodeInfo instance by index - sounds rather fragile to me.
        /// </summary>
        /// <param name="mimeType"></param>
        /// <returns></returns>
        private ImageCodecInfo GetImageCodeInfo(string mimeType)
        {
            var info = ImageCodecInfo.GetImageEncoders();

            foreach (var ici in info)
            {
                if (ici.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase))
                {
                    return ici;
                }
            }

            return null;
        }

        /// <summary>
        /// Calculates picture dimensions whilst maintaining aspect
        /// </summary>
        /// <param name="originalSize">The original picture size</param>
        /// <param name="PictureSize">The target picture size (longest side)</param>
        /// <returns></returns>
        private Size CalculateDimensions(Size originalSize)
        {
            var newSize = new Size();

			if(PictureSize <= 0 || PictureSize > originalSize.Width * 1.4)
			{
				return originalSize;
			}

			if((float)originalSize.Height / (float)originalSize.Width > 0.75)
			{
				var newHeight = (float)PictureSize * 0.75;
				var newWidth = newHeight * (float)originalSize.Width / (float)originalSize.Height;

				newSize.Height = (int)newHeight;
				newSize.Width = (int)newWidth;
			}
			else
			{
				newSize.Width = PictureSize;
				newSize.Height = (PictureSize * originalSize.Height) / originalSize.Width;
			}

            return newSize;
        }
    }
}
